using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Text;

using ExchangeHog.Pop3Client.Responses;

namespace ExchangeHog.Pop3Client.Commands
{
	internal sealed class ListCommand : Pop3Command<ListResponse>
	{
		int _messageId;

		public ListCommand(Stream stream): base(stream, true, Pop3State.Transaction) { }

		public ListCommand(Stream stream, int messageId): this(stream)
		{
			if (messageId < 0)
				throw new ArgumentOutOfRangeException("messageId");

			_messageId = messageId;

			base.IsMultiline = false;
		}

		protected override byte[] CreateRequestMessage()
		{
			string requestMessage = Pop3Commands.List;

			//
			// Append the message id to perform the LIST command for.
			//
			if (!IsMultiline)
				requestMessage += _messageId.ToString();

			return GetRequestMessage(requestMessage, Pop3Commands.Crlf);
		}

		protected override ListResponse CreateResponse(byte[] buffer)
		{
			Pop3Response response = Pop3Response.CreateResponse(buffer);

			var items = new List<Pop3ListItem>();

			if (IsMultiline)
			{
				string[] lines = GetResponseLines(StripPop3HostMessage(buffer, response.HostMessage));

				foreach (string line in lines)
				{
					//
					//	each line should consist of 'n m' where n is the message number and m is the number of octets
					//
					string[] values = line.Split(' ');
					if (values.Length < 2)
						throw new Pop3Exception(string.Concat("Invalid line in multiline response:  ", line));

					items.Add(new Pop3ListItem(Convert.ToInt32(values[0]),
						Convert.ToInt64(values[1])));
				}
			}
			else
			{
				string[] values = response.HostMessage.Split(' ');

				//
				//	should consist of '+OK messageNumber octets'
				//
				if (values.Length < 3)
					throw new Pop3Exception(string.Concat("Invalid response message: ", response.HostMessage));
				items.Add(new Pop3ListItem(Convert.ToInt32(values[1]), Convert.ToInt64(values[2])));
			}

			return new ListResponse(response, items);
		}
	}
}
